from pmapi import config
from pmapi import utils
from pmapi import log
from pmapi import git
from pmapi import lock
import json
import os
import sqlite3
import time


def update() -> None:  # 更新数据库，如 apt update
    lockn = lock.Lock("update")  # 加锁
    log.info("update")
    # sources 解析
    try:
        with open(utils.get_builtin_dir("sources.json"), "r") as file:
            file_json = json.load(file)
    except json.decoder.JSONDecodeError:  # json格式错误
        log.err(f"update database failed: " +
                "Json syntax error")
        lockn.remove()
        return 3
    except Exception as exp:
        log.err(f"update database failed: " +
                "Unknown error in read file ("+repr(exp)+")")
        lockn.remove()
        return 2

    db_path = utils.get_builtin_dir("database")  # 获取数据库目录

    if "sources" not in file_json:  # 语法校验
        log.err(f"update database failed: " +
                "Json syntax error (lost \"sources\")")
        lockn.remove()
        return 4
    try:
        db_list = [i["git"] for i in file_json["sources"]]  # 生成db列表
    except:  # 缺少 git 键
        log.err(f"update database failed: " +
                "Json syntax error (lost \"git\" "+repr(exp)+")")
        lockn.remove()
        return 5

    mirrors = {}
    if "mirrors" in file_json:  # 镜像语法校验
        if type(file_json["mirrors"]) != dict:
            log.err(f"update database failed: " +
                    "Json syntax error (\"mirrors\" is not dict)")
            lockn.remove()
            return 6

    # 处理缓存未清理
    if os.path.exists(db_path+"/"+'database.bak.db'):
        os.remove(db_path+"/"+'database.bak.db')

    # 镜像替换
    for i in db_list:
        for (j, k) in mirrors.items():
            i = i.replace(j, k)

    # 初始化数据库
    log.info("init database")
    conn = sqlite3.connect(db_path+"/"+'database.bak.db')
    cursor = conn.cursor()
    # 创建表头
    cursor.execute(
        "CREATE TABLE `sources` (`name` TEXT PRIMARY KEY UNIQUE NOT NULL, `repo` TEXT NOT NULL, `description` TEXT, `keywords` TEXT, `author` TEXT)")
    conn.commit()
    cursor.execute('PRAGMA table_info(sources);')
    table_info = cursor.fetchall()

    log.info("start update")
    n: int = 0
    for i in db_list:  # 执行操作
        db_name = i.split("/")[-1]
        db_loacl_name = db_name.replace(".git", "")
        if not os.path.exists(db_path+"/"+db_loacl_name):
            log.info("clone source: "+i)
            git.clone(i, db_path+"/"+db_loacl_name, depth=1)
        else:
            log.info("pull source: "+i)
            git.pull(db_path+"/"+db_loacl_name)
        time.sleep(0.2)
        # 合并仓库
        for j in file_json["sources"][n]["types"]:
            time.sleep(0.2)
            if not os.path.exists(db_path+"/"+db_loacl_name+"/"+j+".db"):
                log.warn("cannot find sources db \""+j+"\"")  # 找不到指定的源
                continue
            # 打开数据库 感谢chatglm
            conn_new = sqlite3.connect(db_path+"/"+db_loacl_name+"/"+j+".db")
            cursor_new = conn_new.cursor()
            cursor_new.execute('SELECT * FROM sources;')
            rows2 = cursor_new.fetchall()
            for row in rows2:
                try:
                    cursor.execute(
                        'INSERT INTO sources VALUES (' + ','.join(['?'] * len(table_info)) + ');', row)
                except sqlite3.IntegrityError:
                    # 如果键重复，则忽略
                    log.warn(f"key {row[0]} defined")
            n += 1
            conn_new.close()
    conn.commit()
    conn.close()
    if os.path.exists(db_path+"/"+'database.db'):
        os.remove(db_path+"/"+'database.db')
    os.rename(db_path+"/"+'database.bak.db', db_path+"/"+'database.db')
    lockn.remove()  # 解锁
